package scau.mis4.chanyulin.view;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import scau.mis4.chanyulin.dao.TempDao;
import scau.mis4.chanyulin.entity.Temp;
import scau.mis4.chanyulin.service.DataSourceService;
import scau.mis4.chanyulin.tools.PeriodTask;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by cyl on 2017/12/5.
 * 传感器温度图像显示
 */
public class SensorDisplay extends Pane {

    private static double refreshSeconds = 0.75;

    private static final double DISPLAY_WIDTH = 300.0;
    private static final double DISPLAY_HEIGHT = 300.0;

    private static final double LOWEST_DEGREE = 0.0;
    private static final double HIGHEST_DEGREE = 50.0;
    private static final double DEGREE_RANGE = HIGHEST_DEGREE - LOWEST_DEGREE;

    private PeriodTask task;
    private Runnable runable;

    double movDis = 5;
    double footX = DISPLAY_WIDTH;
    double footY = DISPLAY_HEIGHT;

    public SensorDisplay() {
        List<Line> vLineList = new LinkedList<>();
        for (int i = 1; i <= DISPLAY_WIDTH; i++) {
            if (i % (movDis * 4) == 0) {
                Line line = new Line(i, 0.0, i, DISPLAY_HEIGHT);
                line.setStroke(Color.LIGHTGREY);
                vLineList.add(line);
                this.getChildren().add(line);
            }
        }
        for (int i = 0; i <= DISPLAY_HEIGHT; i++) {
            if (i % (movDis * 4) == 0) {
                Line line = new Line(0.0, i, DISPLAY_WIDTH, i);
                line.setStroke(Color.LIGHTGREY);
                this.getChildren().add(line);
            }
        }

        Polygon polygon = new Polygon();
        polygon.setStroke(Color.GREEN);
        polygon.setFill(Color.LIGHTGREEN);
        polygon.setOpacity(0.50);

        this.getChildren().addAll(polygon);
        this.setPrefSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
        this.setStyle("-fx-border-color: gainsboro");

        /* ------ 定时器 ------ */
        runable = () -> {
            Platform.runLater(() -> {
                // TODO 修改传感器温度获取方法
                Temp tempObj = DataSourceService.randomTemperObject();
                double randTemp = tempObj.getAvg();
                Global.senTempProp.setValue(String.valueOf(String.format("%.1f", randTemp)) + "℃");
                if (randTemp >= 28.0 || randTemp <= 22.0) {
                    polygon.setStroke(Color.DARKRED);
                    polygon.setFill(Color.RED);
                    if (Global.senTempImgBox.getChildren().get(0) == Global.TEMP_GREEN)
                        Global.senTempImgBox.getChildren().set(0, Global.TEMP_RED);
                } else {
                    polygon.setStroke(Color.GREEN);
                    polygon.setFill(Color.LIGHTGREEN);
                    if (Global.senTempImgBox.getChildren().get(0) == Global.TEMP_RED)
                        Global.senTempImgBox.getChildren().set(0, Global.TEMP_GREEN);
                }
                // 保存温度数据
                if (Global.DB_CONN_CHECKER.isNetworkAvailable()) TempDao.add(tempObj);

                double tarX = DISPLAY_WIDTH;
                double tarY = DISPLAY_HEIGHT - DISPLAY_HEIGHT * randTemp / DEGREE_RANGE;

                ObservableList<Double> pointList = polygon.getPoints();
                if (pointList.size() == 0) {
                    pointList.add(tarX);
                    pointList.add(tarY);
                    pointList.add(footX);
                    pointList.add(footY);
                    return;
                }
                for (int i = 0; i < pointList.size(); i++) {
                    if (i % 2 == 0) pointList.set(i, pointList.get(i) - movDis);
                }
                footX = pointList.get(pointList.size() - 2);
                if (pointList.size() == 2) {
                    pointList.remove(pointList.size() - 2, pointList.size());
                } else {
                    pointList.remove(pointList.size() - 4, pointList.size());
                }
                pointList.add(tarX);
                pointList.add(tarY);
                if (pointList.get(0) < 0.0) {
                    pointList.remove(0, 2);
                    footX = 0.0;
                    pointList.set(0, footX);
                }

                pointList.add(tarX);
                pointList.add(DISPLAY_HEIGHT);
                pointList.add(footX);
                pointList.add(footY);

                for (int i = 0; i < vLineList.size(); i++) {
                    Line line = vLineList.get(i);
                    line.setStartX(line.getStartX() - movDis);
                    line.setEndX(line.getEndX() - movDis);
                }
                if (vLineList.get(0).getStartX() <= 1.0) {
                    Line line = vLineList.get(0);
                    line.setStartX(DISPLAY_WIDTH);
                    line.setEndX(DISPLAY_WIDTH);
                    vLineList.remove(0);
                    vLineList.add(line);
                }
            });
        };
        /* ------------------ */
    }

    public double getRefreshSeconds() {
        return refreshSeconds;
    }

    public void setRefreshSeconds(double refreshSeconds) {
        SensorDisplay.refreshSeconds = refreshSeconds;
    }

    public void stop() {
        task.cancel();
    }

    public void start() {
        task = new PeriodTask(runable);
        task.setPeriod(refreshSeconds);
        task.schedule();
    }

}
